﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text;

namespace Query2Object
{
    /// <summary>
    /// Handle the data context,load the context dll,it's a singleton object.
    /// 维护数据访问的上下文，在初始化的时候根据配置加载上下文dll，采用SingleTon模式，所以在系统里只有一个实例
    /// </summary>
    public class dbContext
    {
        private static readonly dbContext instance = new dbContext();

        private SortedDictionary<string, IDbContext> contexts;

        /// <summary>
        /// init the data context,use config file to load context dll
        /// 初始化数据上下文，通过反射动态根据配置文件加载数据上下文的dll。
        /// </summary>
        private dbContext()
        {
            try
            {
                IDbContext ctx = null;
                contexts = new SortedDictionary<string, IDbContext>();
                //Use cycle to loop all database setting name in config file
                //循环配置文件里的add项，为每一个配置的数据库加载上下文Dll
                foreach (string key in Configs.Keys)
                {
                    if (!contexts.ContainsKey(key))
                    {
                        ctx = DllLoader.TryLoadContext(Configs.dbtypes[key]);
                        ctx.ConnectionString = Configs.connections[key];
                        contexts.Add(key, ctx);
                    }
                }
            }
            catch (ContextDllLoadException ex)
            {
                throw new Query2ObjectException("dll load or type load error!", ex);
            }
            catch (Exception ex)
            {
                throw new Query2ObjectException("UnKown Error!", ex);
            }
        }
        /// <summary>
        /// get current dbContext containner instance 
        /// 获取系统中的数据上下文容器对象
        /// </summary>
        /// <returns>Current Instance(返回当前上下文对象)</returns>
        public static dbContext Current()
        {
            return instance;
        }
        /// <summary>
        /// Get Data Context Instance
        /// 获取数据上下文对象
        /// </summary>
        /// <param name="Id">add name 配置的名称</param>
        /// <returns>Data Context Instance 上下文对象</returns>
        public IDbContext GetContext(string Id)
        {
            if (!contexts.ContainsKey(Id))
            {
                throw new Query2ObjectException("No Such Setting", null);
            }
            return contexts[Id];
        }
    }
}
